# 指定文件编码为UTF-8
# coding: utf-8

"""
visualize_filter.py 功能说明：
1. 可视化卷积神经网络的滤波器权重
2. 支持显示随机初始化的滤波器和训练后的滤波器
3. 使用网格布局展示多个滤波器
4. 可以直观比较训练前后滤波器的变化

关键点：
- 滤波器权重可视化有助于理解CNN学习到的特征
- 随机初始化的滤波器通常呈现噪声模式
- 训练后的滤波器会学习有意义的特征检测器
- 使用灰度图显示滤波器权重
- 自动调整网格布局以适应滤波器数量
"""

# 导入NumPy数值计算库
import numpy as np
# 导入matplotlib绘图库
import matplotlib.pyplot as plt
# 从simple_convnet导入简单卷积网络类
from simple_convnet import SimpleConvNet

def filter_show(filters, nx=8, margin=3, scale=10):
    """
    可视化卷积滤波器的函数

    参数:
        filters: 滤波器权重数组(FN, C, FH, FW)
        nx: 每行显示的滤波器数量(默认8)
        margin: 子图间距(默认3)
        scale: 显示比例(默认10)
    """
    # 获取滤波器形状(数量,通道,高,宽)
    FN, C, FH, FW = filters.shape
    # 计算需要的行数
    ny = int(np.ceil(FN / nx))

    # 创建图形并调整子图间距
    fig = plt.figure(figsize=(scale, scale*ny/nx))
    fig.subplots_adjust(left=0, right=1, bottom=0, top=1,
                      hspace=0.05, wspace=0.05)

    # 绘制每个滤波器的权重
    for i in range(FN):
        ax = fig.add_subplot(ny, nx, i+1, xticks=[], yticks=[])
        # 显示第一个通道的滤波器权重(灰度图)
        ax.imshow(filters[i, 0], cmap=plt.cm.gray_r, interpolation='nearest')
    plt.show()

# 初始化简单卷积网络
network = SimpleConvNet()

# 1. 显示随机初始化的滤波器权重
print("随机初始化的滤波器:")
filter_show(network.params['W1'])

# 2. 加载训练好的权重并显示
print("训练后的滤波器:")
network.load_params("params.pkl")  # 加载预训练参数
filter_show(network.params['W1'])

"""
可视化结果分析：
1. 随机初始化的滤波器：
   - 呈现随机噪声模式
   - 权重值分布均匀
   - 没有明显的特征检测模式

2. 训练后的滤波器：
   - 呈现有规律的边缘检测模式
   - 可能包含不同方向的边缘检测器
   - 有些滤波器可能对特定纹理敏感
   - 权重值分布不再均匀

使用说明：
1. 需要先训练网络并保存参数(params.pkl)
2. 可以调整nx参数改变每行显示的滤波器数量
3. 滤波器显示的是第一个通道的权重
4. 灰度图中白色表示正权重，黑色表示负权重
"""
